package com.rxmvp.rxmvpdemo.RxRetrofit;

import android.app.Application;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.io.File;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.Cache;
import okhttp3.OkHttpClient;
import okhttp3.internal.tls.OkHostnameVerifier;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

import static com.jakewharton.byteunits.DecimalByteUnit.MEGABYTES;

/**
 * 初始化Retrofit，获取一个retrofit对象
 *
 * 作者： huangRZ on 2017/1/21. 15:04
 * 邮箱：917647409@qq.com
 */
public class RetrofitClient {

    //baseUrl: 一般为服务器的域名
    private static final String baseUrl = "http://v.juhe.cn/";

    static final int DISK_CACHE_SIZE = (int) MEGABYTES.toBytes(50); //磁盘缓存的大小
    private static final int READ_TIME_OUT = 10 * 1000;        //读取超时时间（单位：毫秒）
    private static final int CONNECT_TIME_OUT = 15 * 1000;     //连接超时时间（单位：毫秒）

    private static RetrofitClient instance;

    //初始化OkHttpClient
    public OkHttpClient client(Application app) {

        File cacheDir = new File(app.getExternalCacheDir(), "http");  //缓存的位置，在android/包名/data/cache文件夹下。
        Cache cache = new Cache(cacheDir, DISK_CACHE_SIZE);     //设置缓存大小

        LauncherTrust launcherTrust = new LauncherTrust();
        return new OkHttpClient.Builder()
                .connectTimeout(CONNECT_TIME_OUT, TimeUnit.MILLISECONDS)
                .readTimeout(READ_TIME_OUT, TimeUnit.MILLISECONDS)
                .sslSocketFactory(sslSocketFactory(launcherTrust), launcherTrust)
                .hostnameVerifier(OkHostnameVerifier.INSTANCE)
                .cache(cache)  //支持缓存
                .addInterceptor(getHttpLoggingInterceptor()) //增加logging日志输出
                .build();
    }

    //获取可以打印log输出日志的拦截器
    private HttpLoggingInterceptor getHttpLoggingInterceptor() {
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(
                new HttpLoggingInterceptor.Logger() {
                    @Override
                    public void log(String message) {
                        Log.i("retrofit", "retrofit:" + message);
                    }
                });
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        return loggingInterceptor;
    }

    //设置gson解析规则
    private Gson gson() {
        //设置gson解析规则，只有@Expose注解的成员变量才会被gson解析到。
        return new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
    }

    //初始化一个retrofit对象
    public Retrofit createClient(Application application) {
        return new Retrofit.Builder()
                .baseUrl(baseUrl)
                .addConverterFactory(GsonConverterFactory.create(gson()))
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .client(client(application))
                .build();
    }

    private RetrofitClient() {
    }
    //单例模式
    public static RetrofitClient getInstance() {
        if (instance == null) {
            synchronized (RetrofitClient.class) {
                if (instance == null) {
                    instance = new RetrofitClient();
                }
            }
        }
        return instance;
    }

    //以下为信任证书的处理，抄袭网上进行实际开发的大神的代码，暂时使用没出现问题。
    private SSLSocketFactory sslSocketFactory(LauncherTrust launcherTrust) {
        try {
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, new TrustManager[]{launcherTrust}, new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            e.printStackTrace();
        }
        return null;
    }

    static class LauncherTrust implements X509TrustManager {

        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

        }

        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }

}
